/**
 ******************************************************************************
 * @file           : studio_geo_c.h
 * @author         : wangyingjie
 * @brief          : 几何矢量类型 C 语言版
 *                  包括： 点、多点、线、环、面 、圆、 三角、 椭圆
 * @attention      : None
 * @date           : 2025/5/10
 ******************************************************************************
 */

#ifndef STUDIO_GEO_C_H
#define STUDIO_GEO_C_H

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>

#define AO_EPSILON 1e-6
#define AO_M_PI 3.14159265358979323846

/****************************************/
/// 点
/****************************************/
typedef struct
{
    double x;
    double y;
} studio_point_c;

/// 初始化点
/// \param xx
/// \param yy
/// \return
studio_point_c studio_point_init(double xx, double yy);

/// 判断两个点是否相等
/// \param p1
/// \param p2
/// \return true 表示 相等
bool studio_point_equal(const studio_point_c* p1, const studio_point_c* p2);

/****************************************/
/// 线
/****************************************/

// 该变量类型的定义为： studio_line_c temp_line = studio_line_c_init();
// 并且 需要调用 studio_line_c_destroy(&temp_line); 释放内存
typedef struct
{
    studio_point_c* data;  // 点数据指针
    unsigned int size;     // 当前元素个数
    unsigned int capacity; // 当前分配的内存容量
} studio_line_c;

// 初始化线段 (默认容量为4)

/// 初始化线
/// @return 返回初始化的点类型
studio_line_c studio_line_c_init();

/// 销毁线段 (释放内存)
/// @param line
void studio_line_c_destroy(studio_line_c* line);

/// 尾部添加点
/// @param line 线段指针
/// @param point 点
void studio_line_c_add_point(studio_line_c* line, studio_point_c point);

/// 从线段中删除指定索引的点
/// \param line 线段指针
/// \param index 要删除的点的索引 (索引从0开始)
/// \return true 表示删除成功，false 表示索引无效
bool studio_line_c_remove_point(studio_line_c* line, unsigned int index);

/// 获取当前元素数量
/// @param line 线段
/// @return 当前元素数量
unsigned int studio_line_c_size(const studio_line_c* line);

// 获取指定位置的点的引用 (注意索引越界问题)

/// 获取指定位置的点的引用，如果下标越界 则返回 (0,0)
/// @param line 线段
/// @param index 索引 (索引从0开始)
/// @return 点
studio_point_c studio_line_c_get_point(const studio_line_c* line, unsigned int index);

/// 修改指定索引位置的值
/// @param line 线段
/// @param index 索引 (索引从0开始)
/// @param point 点
/// @return true 表示修改成功，false 表示索引无效
bool studio_line_c_set_point(studio_line_c* line, unsigned int index, studio_point_c point);

/****************************************/
/// 矩形框
/****************************************/
typedef struct
{
    studio_point_c left_top;
    studio_point_c right_bottom;
} studio_rect_c;

studio_rect_c studio_rect_init(double l, double t, double r, double b);

/// 矩形框校正
/// \param rect
void studio_rect_correct(studio_rect_c* rect);

/// 矩形框是否相交
/// \param r1
/// \param r2
/// \return
bool studio_rect_intersect(const studio_rect_c* r1, const studio_rect_c* r2);

/****************************************/
/// 圆
/****************************************/
typedef struct
{
    studio_point_c center;
    double radius;
} studio_circle_c;

/// 初始化圆
/// \param center 圆心
/// \param radius 半径
/// \return
studio_circle_c studio_circle_init(studio_point_c center, double radius);

/// 计算圆的面积
/// \param circle
/// \return
double studio_circle_area(const studio_circle_c* circle);

/****************************************/
/// 三角形
/****************************************/
typedef struct
{
    studio_point_c a;
    studio_point_c b;
    studio_point_c c;
} studio_triangle_c;

/// 初始化三角形
/// \param a
/// \param b
/// \param c
/// \return
studio_triangle_c studio_triangle_init(studio_point_c a, studio_point_c b, studio_point_c c);

/// 计算三角形的面积
/// \param triangle
/// \return
double studio_triangle_oriented_area(const studio_triangle_c* triangle);

/// 计算三角形的面积
/// \param triangle
/// \return
double studio_triangle_area(const studio_triangle_c* triangle);

/****************************************/
/// 椭圆
/****************************************/
typedef struct
{
    studio_point_c center;
    double rx;
    double ry;
} studio_ellipse_c;

studio_ellipse_c studio_ellipse_init(studio_point_c center, double rx, double ry);

/// 计算椭圆的面积
/// \param ellipse
/// \return
double studio_ellipse_area(const studio_ellipse_c* ellipse);

/// 计算椭圆的周长
/// \param ellipse
/// \param Ramanujan
/// \return
double studio_ellipse_circumference(const studio_ellipse_c* ellipse, int Ramanujan);

#endif  //  STUDIO_GEO_C_H